package com.example.springboot.controller;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.springboot.config.interceptor.AuthAccess;
import com.example.springboot.entity.Files;
import com.example.springboot.entity.PtsFileEntity;
import com.example.springboot.mapper.FileMapper;
import com.example.springboot.utils.SystemUtil;
import io.swagger.models.auth.In;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import com.example.springboot.utils.AjaxResult;
import com.example.springboot.service.IFileService;

import java.io.File;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;

import java.util.List;

import org.springframework.web.multipart.MultipartFile;
import com.example.springboot.utils.PageData;
import java.util.HashMap;
import java.util.Map;
import java.io.InputStream;
import java.net.URLEncoder;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import org.springframework.web.bind.annotation.RestController;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author cpf
 *
 */
@RestController
@RequestMapping("/file")
public class FileController {

    @Resource
    private IFileService fileService;

    @Resource
    private FileMapper fileMapper;
    @Value("${path.FILE_PATH_WINDOWS}")
    private String FILE_PATH_WINDOWS;
    @Value("${path.FILE_PATH_LINUX}")
    private String FILE_PATH_LINUX;

    private static final String FILE_UPLOAD_PATH = System.getProperty("user.dir") + File.separator + "/files/";
    private static final String FILE_UPLOAD_PART_PATH = System.getProperty("user.dir") + File.separator + "/partImg/";


    /**
     * 文件上传接口
     *
     * @param file 前端传递过来的文件
     * @return
     * @throws IOException
     */
    @AuthAccess
    @RequestMapping(value = "/upload",method = RequestMethod.POST)
    public AjaxResult upload(@RequestParam MultipartFile file) throws IOException {
        try {
            String originalFilename = file.getOriginalFilename();
            String type = FileUtil.extName(originalFilename);
            long size = file.getSize();

            // 定义一个文件唯一的标识码
            String fileName = originalFilename;
            File uploadFile = new File(FILE_UPLOAD_PATH +fileName );
            // 判断配置的文件目录是否存在，若不存在则创建一个新的文件目录
            File parentFile = uploadFile.getParentFile();
            if (!parentFile.exists()) {
                parentFile.mkdirs();
            }
            String url ="";
            file.transferTo(uploadFile);
            if(SystemUtil.isWindows()){
                url = FILE_PATH_WINDOWS + fileName;
            }else if(SystemUtil.isLinux()){
                url = FILE_PATH_LINUX + fileName;
            }

            Map<String,String> data = new HashMap<>();
            data.put("imgUrl",url);
            return AjaxResult.success("上传成功",data);
        }catch (Exception e){
            return AjaxResult.failure("请查看日志");
        }
    }
    /**
     * 文件上传接口
     *
     * @param file 前端传递过来的文件
     * @return
     * @throws IOException
     */
    @AuthAccess
    @RequestMapping(value = "/uploadPart",method = RequestMethod.POST)
    public AjaxResult uploadPart(@RequestParam MultipartFile file) throws IOException {
        try {
            String originalFilename = file.getOriginalFilename();
            String type = FileUtil.extName(originalFilename);
            long size = file.getSize();

            // 定义一个文件唯一的标识码
            String fileName = originalFilename;
            File uploadFile = new File(FILE_UPLOAD_PART_PATH +fileName );
            // 判断配置的文件目录是否存在，若不存在则创建一个新的文件目录
            File parentFile = uploadFile.getParentFile();
            if (!parentFile.exists()) {
                parentFile.mkdirs();
            }
            String url ="";
            file.transferTo(uploadFile);
            if(SystemUtil.isWindows()){
                url = FILE_PATH_WINDOWS + fileName;
            }else if(SystemUtil.isLinux()){
                url = FILE_PATH_LINUX + fileName;
            }

            Map<String,String> data = new HashMap<>();
            data.put("imgUrl",url);
            return AjaxResult.success("上传成功",data);
        }catch (Exception e){
            return AjaxResult.failure("请查看日志");
        }
    }
    /**
     * 文件下载接口
     *
     * @param fileUUID
     * @param response
     * @throws IOException
     */
    @GetMapping("/download/{fileUUID}")
    public void download(@PathVariable String fileUUID, HttpServletResponse response) throws IOException {
//        fileUUID = fileUUID.split("\\.")[0];
        // 根据文件的唯一标识码获取文件
        File uploadFile = new File(FILE_UPLOAD_PATH + fileUUID);
        // 设置输出流的格式
        ServletOutputStream os = response.getOutputStream();
        response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileUUID, "UTF-8"));
        response.setContentType("application/octet-stream");

        // 读取文件的字节流
        try {
            os.write(FileUtil.readBytes(uploadFile));
        } catch (Exception e) {
            System.err.println("文件下载失败，文件不存在");
        }
        os.flush();
        os.close();
    }


    /**
     * 通过文件的md5查询文件
     *
     * @param md5
     * @return
     */
    private Files getFileByMd5(String md5) {
        // 查询文件的md5是否存在
        Map<String,Object> param = new HashMap<>();
        param.put("md5",md5);
        List<Files> filesList = fileMapper.queryAllInfo(param);
        return filesList.size() == 0 ? null : filesList.get(0);
    }

    @PostMapping("/update")
    public AjaxResult update(@RequestBody Files files) {
        try {
            fileMapper.update(files);
            return AjaxResult.success("修改成功");
        }catch (Exception e){
            e.printStackTrace();
            return AjaxResult.failure("请查看日志");
        }
    }

    // 新增或者更新
    @RequestMapping(value = "/save",method = RequestMethod.POST)
    public AjaxResult save(@RequestBody Files file) {
        try{
            Files fileData = fileService.queryById(file.getId());
            if(fileData == null){
                //save
                fileService.insert(file);
                return AjaxResult.success("添加成功！");
            }else{
                fileService.update(file);
                return AjaxResult.success("修改成功！");
            }
            //if (file.getId() == null) {
            //file.setTime(DateUtil.now());
            //file.setUser(TokenUtils.getCurrentUser().getUsername());
            //}


        }catch(Exception e){
            e.printStackTrace();
            return AjaxResult.failure("请查看日志");
        }

    }
    @RequestMapping(value = "/{id}",method = RequestMethod.DELETE)
    public AjaxResult delete(@PathVariable Integer id) {
        try{
            Files files = fileMapper.queryById(id);
            files.setIsDelete("1");
            fileMapper.update(files);
            return AjaxResult.success("删除成功");
        }catch(Exception e){
            e.printStackTrace();
            return AjaxResult.failure("请查看日志");
        }
    }

    @RequestMapping(value = "/del/batch",method = RequestMethod.DELETE)
    public AjaxResult deleteBatch(@RequestBody List<Integer> ids) {
        try{
            fileService.deleteByIds(ids);
            return AjaxResult.success("删除成功！");
        }catch(Exception e){
            e.printStackTrace();
            return AjaxResult.failure("请查看日志");
        }
    }

    @RequestMapping(value = "/findAll",method = RequestMethod.GET)
    public AjaxResult findAll() {
        try{
            Map<String,Object> param = new HashMap<>();
            List<Files> fileList = fileService.queryAllInfo(param);
            return AjaxResult.success("查询成功",fileList);
        }catch(Exception e){
            e.printStackTrace();
            return AjaxResult.failure("请查看日志");
        }
    }

    @RequestMapping(value = "/{fileUUID}",method = RequestMethod.GET)
    public AjaxResult findOne(@RequestParam("fileUUID") String fileUUID) {
        try{
            File file = new File(FILE_UPLOAD_PATH + fileUUID);
            return AjaxResult.success("查询成功",file);
        }catch(Exception e){
            e.printStackTrace();
            return AjaxResult.failure("请查看日志");
        }
    }

    @RequestMapping(value = "/page",method = RequestMethod.POST)
    public AjaxResult findPage(@RequestBody Map<String,Object> param) {
        try{

            //User currentUser = TokenUtils.getCurrentUser();
            //if (currentUser.getRole().equals("ROLE_USER")) {
                //queryWrapper.eq("user", currentUser.getUsername());
            //}
            int pageSize = Integer.parseInt(String.valueOf(param.get("pageSize")));
            int page = Integer.parseInt(String.valueOf(param.get("page")));
            int startIndex = (page - 1) * pageSize;
            param.put("pageIndex",startIndex);
            long count = fileService.count(param);
            List<Files> fileList = fileService.queryAllInfo(param);
            PageData pageData = new PageData(page, pageSize, fileList, count);
            return AjaxResult.success("查询成功！",pageData);
        }catch(Exception e){
            e.printStackTrace();
            return AjaxResult.failure("请查看日志");
        }
    }

    /**
    * 导出接口
    */
    @RequestMapping(value = "/export",method = RequestMethod.GET)
    public void export(HttpServletResponse response) throws Exception {
        try{
            // 从数据库查询出所有的数据,查询条件为空
            Map<String,Object> param = new HashMap<>();
            List<Files> list = fileService.queryAllInfo(param);
            // 在内存操作，写出到浏览器
            ExcelWriter writer = ExcelUtil.getWriter(true);

            // 一次性写出list内的对象到excel，使用默认样式，强制输出标题
            writer.write(list, true);

            // 设置浏览器响应的格式
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
            String fileName = URLEncoder.encode("File信息表", "UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");

            ServletOutputStream out = response.getOutputStream();
            writer.flush(out, true);
            out.close();
            writer.close();
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    /**
     * excel 导入
     * @param file
     * @throws Exception
     */
    @RequestMapping(value = "/import",method = RequestMethod.POST)
    public AjaxResult importFile(MultipartFile file) throws Exception {
        try{
            InputStream inputStream = file.getInputStream();
            ExcelReader reader = ExcelUtil.getReader(inputStream);
            // 通过 javabean的方式读取Excel内的对象，但是要求表头必须是英文，跟javabean的属性要对应起来
            List<Files> list = reader.readAll(Files.class);

            fileService.insertBatch(list);
            return AjaxResult.success("导入成功");
        }catch(Exception e){
            e.printStackTrace();
            return AjaxResult.failure("请查看日志");
        }
    }

}

